<?php

namespace App\Http\Model;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class RedPacketRain extends Base
{
    protected $table = 'red_packet_rain';
    protected $rprTable = 'red_packet_rain_log';

    //红包雨红包奖池缓存
    protected $redPacketRainPoolKey = 'REDPACKETRAIN:POOLDATA:';//list REDPACKETRAIN:POOLDATA:{rain_id}:{ymdhis} => {string}
    //红包雨用户的红包金额缓存
    protected $redPacketRainUserDrawKey = 'REDPACKETRAIN:USERDRAW:';//string REDPACKETRAIN:USERDRAW:{rain_id}:{userId} => {num}

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
    }

    //新增红包雨
    public function addRedPacketRain($startTime, $rechargeDiamondNum, $allDiamondNum, $packetNum, $minNum, $maxNum, $adminId)
    {
        $data = [];
        $data['start_time'] = $startTime;
        $data['limit_second'] = 10;
        $data['recharge_diamond_num'] = $rechargeDiamondNum;
        $data['all_diamond_num'] = $allDiamondNum;
        $data['packet_num'] = $packetNum;
        $data['min_num'] = $minNum;
        $data['max_num'] = $maxNum;
        $data['admin_id'] = $adminId;
        $id = DB::table($this->table)->insertGetId($data);
        return $id;
    }

    //编辑红包雨
    public function editRedPacketRain($rainId, $params)
    {
        $upData = [];
        if(!empty($params['start_time'])) {
            $upData['start_time'] = $params['start_time'];
        }
        if(isset($params['recharge_diamond_num'])) {
            $upData['recharge_diamond_num'] = $params['recharge_diamond_num'];
        }
        if(!empty($params['all_diamond_num'])) {
            $upData['all_diamond_num'] = $params['all_diamond_num'];
        }
        if(!empty($params['packet_num'])) {
            $upData['packet_num'] = $params['packet_num'];
        }
        if(!empty($params['min_num'])) {
            $upData['min_num'] = $params['min_num'];
        }
        if(!empty($params['max_num'])) {
            $upData['max_num'] = $params['max_num'];
        }
        if(!empty($params['is_delete'])) {
            $upData['is_delete'] = $params['is_delete'];
        }
        if(!empty($params['admin_id'])) {
            $upData['admin_id'] = $params['admin_id'];
        }

        if(empty($upData)) {
            return 0;
        }

        $res = DB::table($this->table)->where('id', $rainId)->update($upData);

        return $res;
    }

    /**
     * 根据时间获取红包雨
     */
    public function getRedPacketRainByTime($timeSt, $timeEd, $noId=0){
        $query = DB::table($this->table)
            ->where('is_delete', 0)
            ->where('start_time', '>', $timeSt)
            ->where('start_time', '<', $timeEd)
        ;

        if(!empty($noId)) {
            $data = $query->where('id', '<>', $noId);
        }
        $data = $query->first();
        $data = self::objToArray($data);

        return $data;
    }

    /**
     * 根据id获取红包雨
     */
    public function getRedPacketRainById($id){
        $data = DB::table($this->table)
            ->where('is_delete', 0)
            ->where('id', $id)
            ->first();
        $data = self::objToArray($data);

        return $data;
    }

    /**
     * 生成红包雨红包奖池
     */
    public function makeRedPacketRainPool($id){
        $data = DB::table($this->table)
            ->where('is_delete', 0)
            ->where('id', $id)
            ->first();
        $data = self::objToArray($data);
        if(empty($data)) {
            return false;
        }
        //清理旧数据
        $delKeys = Redis::keys($this->redPacketRainPoolKey.$id.':*');
        if(!empty($delKeys)) {
            redis::DEL($delKeys);
        }

        $startTime = date('YmdHis', strtotime($data['start_time']));
        $limitSecond = $data['limit_second'];//持续秒数
        $packetNum = $data['packet_num'];//总个数
        $minNum = $data['min_num'];//每个最小值
        $maxNum = $data['max_num'];//每个最大值
        $secondNum = intval($packetNum/$limitSecond);//每秒可领取红包数
        //红包数据
        $redPackList = [];
        for($i=0;$i<$packetNum;$i++) {
            $redPackList[] = rand($minNum, $maxNum);
        }
        //每秒数据处理
        for($i=0;$i<$limitSecond;$i++) {
            $cacheKey = $this->redPacketRainPoolKey.$id.':'.($startTime+$i);
            //最后一秒把所有剩余都放进去
            if($i == ($limitSecond-1)) {
                while(count($redPackList) > 0) {
                    $num = array_pop($redPackList);
                    if($num > 0) {
                        Redis::LPUSH($cacheKey, $num);
                    }
                }
            }else{
                //根据每秒可领取红包数写入
                for($k=0;$k<$secondNum;$k++) {
                    $num = array_pop($redPackList);
                    if($num > 0) {
                        Redis::LPUSH($cacheKey, $num);
                    }
                }
            }
        }

        return true;
    }

    /**
     * 判断红包雨奖池是否已生成
     */
    public function checkRedPacketRainPoolHas($id){
        $data = DB::table($this->table)
            ->where('is_delete', 0)
            ->where('id', $id)
            ->first();
        $data = self::objToArray($data);
        if(empty($data)) {
            return 0;
        }
        $startTime = date('YmdHis', strtotime($data['start_time']));
        $limitSecond = $data['limit_second'];//持续秒数
        $packetNum = $data['packet_num'];//总个数

        //检查生成的数量对不对
        $nowNum = 0;
        for($i=0;$i<$limitSecond;$i++) {
            $cacheKey = $this->redPacketRainPoolKey.$id.':'.($startTime+$i);
            $num = Redis::LLEN($cacheKey);
            $nowNum = $nowNum + intval($num);
            if($num > 0) {
                Redis::EXPIRE($cacheKey, 3600);
            }
        }
        if($nowNum != $packetNum) {
            return 0;
        }

        return 1;
    }

    /**
     * 红包雨抽奖
     */
    public function drawRedPacketRain($userId, $data, $now){
        $startTime = date('YmdHis', strtotime($data['start_time']));
        $limitSecond = $data['limit_second'];//持续秒数
        $nowNum = $now - strtotime($data['start_time']);

        $num = 0;
        for($i=0;$i<$limitSecond;$i++) {
            if($i > $nowNum) {
                break;
            }
            $cacheKey = $this->redPacketRainPoolKey.$data['id'].':'.($startTime+$i);
            if(Redis::EXISTS($cacheKey)) {
                $num = Redis::LPOP($cacheKey);
            }
            if($num > 0) {
                break;
            }
        }

        //缓存记录用户参与了活动
        $cacheKey = $this->redPacketRainUserDrawKey.$data['id'].':'.$userId;
        Redis::SET($cacheKey, $num);
        Redis::EXPIRE($cacheKey, 60);

        return $num;
    }

    //判断用户是否参加了活动
    public function checkUserRedPacketRain($rainId, $userId)
    {
        $cacheKey = $this->redPacketRainUserDrawKey.$rainId.':'.$userId;
        $num = (int) Redis::GET($cacheKey);

        return $num;
    }

    //新增红包雨记录
    public function addRedPacketRainLog($data)
    {
        $id = DB::table($this->rprTable)->insertGetId($data);

        return $id;
    }

    //获取红包雨记录
    public function getRedPacketRainLogList($rainId)
    {
        $data = DB::table($this->rprTable)
            ->where('rain_id', $rainId)
            ->get();
        $data = self::objToArray($data);

        return $data;
    }

}
